const SIZE_LIMIT: usize = 0x1fff;

#[derive(Eq, PartialEq, Copy, Clone, Debug)]
enum NumberType {
    Prime,
    GoldbachComposite,
    NonGoldbachComposite,
}

pub fn goldbach_conjecture() -> u64 {
    let mut numbers = [NumberType::Prime; SIZE_LIMIT];
    let mut primes = Vec::with_capacity(SIZE_LIMIT);
    for num in 2..SIZE_LIMIT {
        if numbers[num] == NumberType::Prime {
            primes.push(num);
        }
        for &prime in primes.iter() {
            let composite = prime * num;
            if composite >= SIZE_LIMIT {
                break;
            }
            numbers[composite] = NumberType::NonGoldbachComposite;
            if num % prime == 0 {
                break;
            }
        }
    }
    for &prime in primes.iter().skip(1) {
        for n in 1..SIZE_LIMIT {
            let goldbach = prime + 2 * n.pow(2);
            if goldbach >= SIZE_LIMIT {
                break;
            }
            if numbers[goldbach] == NumberType::NonGoldbachComposite {
                numbers[goldbach] = NumberType::GoldbachComposite;
            }
        }
    }
    numbers
        .iter()
        .enumerate()
        .filter_map(|(num, &tp)| {
            if tp == NumberType::NonGoldbachComposite && num % 2 == 1 {
                Some(num)
            } else {
                None
            }
        })
        .take(2)
        .sum::<usize>() as u64
}
